<?php
namespace Admin\Controller;
use Think\Controller;
use Common\Controller\BaseController;
use Admin\Controller\ChargeController;

header("Content-type: text/html; charset=utf-8");

/**
 * 单位信息管理
 * Class ContactController
 * @package Admin\Controller
 */
class ContactController extends BaseController {

    static $type = array("廉租房", "公租房");
    static $derate_type = array(
        array("无租金减免", 0),
        array("1至6级军残全额减免", 1),
        array("7级以上军残一半减免", 0.5)
    );

    /**
     * 系统管理 -> 系统管理 -> 建筑物信息维护 -> listview
     */
    public function index(){
        //获取搜索条件
        $filter = $this->fn_GenerateFilter();
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();

        //分页信息
        $pageNum = intval(I("post.page"));
        $pageNum = $pageNum==0?1:$pageNum;
        $page = $this->fn_GetPageInfo($where, $pageNum);
        $this->assign("page", $page);

        //搜索出小区信息
        $limit = ($page['from']-1).",".$page['num'];
        $list = M("contact")->where($where)->order($order)->limit($limit)->select();
        for($i=0; $i<count($list); $i++){
            $list[$i]["offset"] = $page['from']-1+$i;
        }
        $this->assign("list", $list);

        //设置community信息
        $this->assign("community", $this->fn_GetCommunityDict());

        //设置搜索条件
        $this->assign("filter", $filter);

        $this->display();
    }

    /**
     * 计划任务程序，将过期的合同信息进行催费处理
     */
    public function scheduler(){

        //第一步：对已过期的合同进行欠费记录；
        echo "开始对已过期的合同进行欠费记录.".'<br />';
        $this->Action_ChargingOverduedContacts();

        //第二步：对即将过期的合同进行年审提醒
        echo "对即将过期的合同进行年审提醒.".'<br />';
        $this->Action_SendOverduingMsg();

    }

    public function Action_ChargingOverduedContacts(){
        $today = date("Y/m/d");
        $map["cn.jsrq"] = array("lt", $today);
        $map["cn.state"] = "已签订"; //有效标识，签订
        $map['cn.yjth'] = '否';
        $total = M("contact")->where($map)->count();

        $pageNum = 100;
        $offset = 0;
        while($offset<$total){
            $con = M("contact cn")
                ->field("cn.*, ch.id")
                ->where($map)
                ->join(C("DB_PREFIX")."charge ch on ch.contact_no=cn.no")
                ->limit($offset . "," . $pageNum)
                ->order("cn.id asc")->select();

            for($i=0; $i<count($con); $i++){
                $data = array(
                    "house_no" => $con[$i]["fwbh"],
                    "house_addr" => $con[$i]["fwdz"],
                    "contact_no" => $con[$i]["no"],
                    "contact_ksrq" => $con[$i]["ksrq"],
                    "contact_jsrq" => $con[$i]["jsrq"],
                    "zj" => $con[$i]["zj"],
                    "mzj" => $con[$i]["mzj"],
                    "jzr" => $con[$i]["yifang"],
                    "jzrdh" => $con[$i]["yfdh"],
                    "cuser" => session("username"),
                    "ctime" => time()
                );
                $res = M("charge")->add($data);
                if($res){
                    echo "欠费信息写入成功，合同编号：".$data['contact_no']."<br />";
                    $res = SmsApiController::SendMsg("4000", $con[$i]['yfdh'], $con[$i]);
                    if(!$res['state']){
                        \Think\Log::write("短信发送失败：".$res['info']);
                    }else{
                        \Think\Log::write("短信发送成功：".$res['phone']);
                    }
                }else{
                    echo "欠费信息写入失败，合同编号：".$data['contact_no']."<br />";
                }
            }
            $offset += $pageNum;
        }
    }

    public function Action_SendOverduingMsg(){
        //只对离合同失效时间还有1个月的时候发送提醒短信
        $map['jsrq'] = date("Y/m/d", strtotime("-1 month"));
        $contacts = M("contact")->field("yfdh, no")->where($map)->select();
        foreach ($contacts as $item) {
            $res = SmsApiController::SendMsg("4000", $item['yfdh'], $item);
            if(!$res['state']){
                \Think\Log::write("短信发送失败：".$res['info']);
            }else{
                \Think\Log::write("短信发送成功：".$res['phone']);
            }
        }
    }

    /**
     * 房屋自动补全搜索算法
     */
    public function ajax_SearchYaohaoByNo(){
        $h = array();
        $where = array("lt.state"=>"待入住", "lt.no"=>array("like", I("get.ywno")."%"));
        $prefix = substr(I("get.ywno"), 0, 1);
        if($prefix=="L"){
            $type = '廉租房';
            $lottery = M("lottery lt")->field("lt.no, lt.house_addr as addr, lt.name, lt.phone, lt.idno,
            h.size, h.price, h.mprice, h.name as hno, l.dibaork, c.name as community")
                ->where($where)
                ->join(C("DB_PREFIX")."lzf l on l.no = lt.no", "LEFT")
                ->join(C("DB_PREFIX")."house h on h.addr = lt.house_addr", "LEFT")
                ->join(C("DB_PREFIX")."community c on c.id = h.community_id", "LEFT")
                ->select();
        }else if($prefix=="G"){
            $type = '公租房';
            $lottery = M("lottery lt")->field("lt.no, lt.house_addr as addr, lt.name, lt.phone, lt.idno,
            h.size, h.price, h.mprice, h.name as hno, g.dibaork")
                ->where($where)
                ->join(C("DB_PREFIX")."gzf g on g.no = lt.no", "LEFT")
                ->join(C("DB_PREFIX")."house h on h.addr = lt.house_addr", "LEFT")
                ->select();
        }else{
            $lottery = array();
        }

        foreach ($lottery as $v){
            $v['type'] = $type;
            $v['yajin'] = C("CONTACT_YAJIN");
            $v['total'] = $this->fn_CalContactZj($v, intval(date("m")), intval(date("d")));
            array_push($h, array("value"=>$v["no"], "data"=>$v));
        }
        $this->ajaxReturn(array('query'=>I("get.ywno"),'suggestions' => $h));
    }

    /**
     * 计算合同租金，结果按四舍五入保留2位小数
     * @param $data
     * @param $dfrom
     * @param $dto
     * @return float|string
     */
    public function fn_CalContactZj($data, $month, $day){
        $month = 12 - $month + max((30-$day),0)/30;
        if($data['dibaork']*13>=$data['size']){ //低保人口享受面积大于房屋面积，则不要出房租
            return $data['size']*1.1*$month;
        }
        //13平米每人内按1.1元每平米的价格计算
        $mzj = ($data['size']-$data['dibaork']*13)*$data['price']/$data['size'] + $data['dibaork']*13*1.1;
        return $mzj*$month;
    }

    /**
     * 房屋自动补全搜索算法
     */
    public function ajax_SearchHouseByName(){
        $h = array();
        $where = array("state"=>"闲置中", "name"=>array("like", "%".I("get.house")."%"));
        $house = M("house")->where($where)->select();
        foreach ($house as $v){
            $v['yajin'] = C("CONTACT_YAJIN");
            array_push($h, array("value"=>$v["name"], "data"=>$v));
        }
        $this->ajaxReturn(array('query'=>I("get.house"),'suggestions' => $h));
    }

    private function fn_GetCommunityList(){
        return M("community")->where()->select();
    }

    private function fn_GetCommunityDict(){
        $community = array();
        $list = M("community")->where()->select();
        for($i=0; $i<count($list); $i++){
            $community[$list[$i]["id"]] = $list[$i]["name"];
        }
        return $community;
    }

    /**
     * 建筑物信息维护 -> formview
     */
    public function detail(){
        //读取单位信息
        $dataId = I("get.id");
        $house = M("contact")->where(array("id"=>$dataId))->find();
        $this->assign("contact", $house);

        //查询条件
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();
        $pageInfo = $this->fn_GetPageInfo($where);

        //页面信息
        $offset = intval(I("get.offset"));
        $nearby = $this->fn_FindNearbyItems($where, $order, $offset);
        $page = array_merge($pageInfo, $nearby);
        $this->assign("page", $page);

        // 设置上下文信息
        $context = $this->fn_GenerateContext($page);
        $this->assign("context", $context);

        //设置community信息
        $options = $this->fn_GetCommunityList();
        $this->assign("options", json_encode ($options));
        $community = $this->fn_GetCommunityDict();
        $this->assign("community", $community);
        $this->display();
    }

    /**
     * 建筑物信息维护 -> 新增
     */
    public function add(){  //todo
        if(IS_POST){    //添加小区信息
            $data = $this->fn_GetFormValues();
            $dataId = M("contact")->add($data);
            //$this->error(M("contact")->getLastSql());
            if($dataId){
                header("Location:/admin/contact/detail?id=".$dataId);
            }else{
                $this->error("系统错误，创建合同失败");
            }
        }

        //复制信息时处理流程
        if(I("get.id") && I("get.action"=="copy")){
            $house = M("contact")->where(array("id"=>I("get.id")))->find();
            $this->assign("contact", $house);
        }

        $contactDate = array(
            "start" => date('Y/m/d'),
            "end" => date('Y')."/12/31"
        );
        $this->assign("type", self::$type);
        $this->assign("derate_type", self::$derate_type);
        $this->assign('contactDate', $contactDate);
        $this->assign("community", $this->fn_GetCommunityList()); //设置community信息
        $this->display();
    }

    private function fn_GetFormValues(){
        return array(
            "no" => "HT".I("post.ywno"),
            "ywno" => I("post.ywno"),
            "community" => I("post.community"),
            "derate_money" => I("post.derate_money"),
            "derate_type" => I("post.derate_type"),
            "state" => "未签订",
            "type" => I("post.type"),
            "dibaork" => I("post.dibaork"),
            "jiafang" => I("post.jiafang"),
            "yifang" => I("post.yifang"),
            "fwbh" => I("post.fwbh"),
            "fwdz" => I("post.fwdz"),
            "size" => I("post.size"),
            "zj" => floatval(I("post.zj")),
            "mzj" => floatval(I("post.mzj")),
            "total" => floatval(I("post.total")),
            "total2" => floatval(I("post.total2")),
            "yj" => floatval(I("post.yj")),
            "ksrq" => I("post.ksrq"),
            "jsrq" => I("post.jsrq"),
            "jffr" => I("post.jffr"),
            "jfjbr" => I("post.jfjbr"),
            "jfdz" => I("post.jfdz"),
            "jfdh" => I("post.jfdh"),
            "yfsfz" => I("post.yfsfz"),
            "yfdw" => I("post.yfdw"),
            "yfdz" => I("post.yfdz"),
            "yfdh" => I("post.yfdh"),
            "remarks" => I("post.remarks"),
            "cuser" => session("username"),
            "ctime" => I("post.ctime")
        );
    }

    public function ajax_CreateContact(){
        $data = $this->fn_GetFormValues();
        $dataId = M("contact")->add($data);
        if($dataId){
            $res = array("no"=>$data['no'],"dataId"=>$dataId);
            $this->success($res);
        }else{
            $this->error("系统错误，创建合同失败");
        }
    }

    /**
     * AJAX方法，在listview中进行批量删除信息
     */
    public function ajax_del(){

        $dataIds = I("post.info");
        if(count($dataIds)==0){
            $this->error("您还没有选中任何记录");
        }

        $draftContact = array();
        $map["id"] = array("in", $dataIds);
        $contact = M("contact")->where($map)->select();
        foreach($contact as $item){
            if($item['state']=='已签订'){
                $this->error("合同:".$item['no']."已生效，无法删除");
            }else{
                $draftContact[] = $item['id'];
            }
        }

        $map["id"] = array("in", $draftContact);
        $res = M("contact")->where($map)->delete();
        if($res){
            $this->success("操作成功");
        }else{
            $this->error("合同已生效，无法删除");
        }
    }

    /**
     * AJAX方法，在formview中进行单条信息删除
     */
    public function ajax_del2(){
        //根据ID删除单位记录
        $id = I("post.id");

        $where = array("id"=>$id, 'state'=>'未签订');
        $contact = M("contact")->where($where)->find();
        if(!$contact){
            $this->error("合同已生效，无法删除");
        }

        $res = M("contact")->where(array("id" => $id))->delete();
        if(!$res){
            $this->error("系统错误");
        }

        //分页信息
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();
        $total = $this->fn_GetTotalItems($where);
        if($total==0){
            $this->success(null);
        }

        //计算下一条记录的offset
        $offset = intval(I("post.offset"));
        $offset = ($offset>=$total-1)?0:$offset;

        //获取下一记录的信息
        $nextItem = $this->fn_GetInfoByOffset($offset, $where, $order);
        $this->success($nextItem["id"]); //返回下一条记录的ID
    }

    /**
     * AJAX方法，通过ID来修改信息
     */
    public function ajax_UpdateInfoById(){
        $data = I("post.data");
        $dataId = I("post.id");
        $res = M("contact")->where(array("id"=>$dataId))->save($data);
        if($res){
            $this->success("0k, 200");
        }else{
            $this->error("更新异常，请稍候再试");
        }
    }

    /**
     *  辅助方法，通过$_POST的值来生成where查询条件
     */
    private function fn_GenerateWhereClause(){
        if(!I("request.value")){
            return array();
        }
        $where = array();
        if(I("request.field")=="community_id"){ //多表查询处理
            $cateIds = $this->fn_SelectCommunityByName(I("request.value"));
            $where[I("request.field")] = array("in", $cateIds);
        }else{
            $where[I("request.field")] = array("like", "%".I("request.value")."%");
        }
        return $where;
    }

    private function fn_SelectCommunityByName($name){
        $where["name"] =  array("like", "%".$name."%");
        $result = M("community")->where($where)->field("id")->select();
        $cateIds = array();
        for($i=0; $i<count($result); $i++){
            array_push($cateIds, $result[$i]["id"]);
        }
        return $cateIds;
    }

    /**
     *  辅助方法，通过$_POST的值来生成order by子句
     */
    private function fn_GenerateOrderBy(){
        $order = "id desc";
        if(I("request.order_field") && I("request.order_sort")){
            $order = I("request.order_field") . " " . I("request.order_sort");
        }
        return $order;
    }

    /**
     *  辅助方法，通过$_POST的值来生成Filter (listview)
     */
    private function fn_GenerateFilter(){
        if(IS_POST){
            return array(
                "page" => I("post.page"),
                "field" => I("post.field"),
                "value" => I("post.value"),
                "order_field" => I("post.order_field"),
                "order_sort" => I("post.order_sort"),
            );
        }
        return array(
            "page" => 1,
            "order_field" => "id",
            "order_sort" => "desc",
        );
    }

    /**
     * 辅助方法，通过$_POST的值来生成Context (formvier)
     * @return array
     */
    private function fn_GenerateContext($page){
        return array(
            "id" => I("request.id"),
            "field" => I("request.field"),
            "value" => I("request.value"),
            "order_field" => I("request.order_field"),
            "order_sort" => I("request.order_sort"),
            "page" => I("request.page"),
            "offset" => I("request.offset"),
            "index" => I("get.offset")-($page["curPage"]-1)*$page["num"]+1
        );
    }

    /**
     * 辅助方法，通过where,order,offset来查询信息
     * @param $offset
     * @param $where
     * @param $order
     * @return mixed
     */
    private function fn_GetInfoByOffset($offset, $where, $order){
        $limit = $offset.",1";
        $res =  M("contact")->field("id,no")->where($where)->order($order)->limit($limit)->select();
        if($res){
            return $res[0];
        }
        return array();
    }

    /**
     * 辅助方法，通过where, curpage, num来生成分页信息
     * @param $where
     * @param int $curPage
     * @param int $num
     * @return array
     */
    private function fn_GetPageInfo($where, $curPage=1, $num=15){
        $total = M("contact")->where($where)->count();
        $totalPage = ceil($total/$num);
        $nextPage = $curPage==$totalPage?1:($curPage+1);
        $prevPage = $curPage==1?$totalPage:($curPage-1);
        $to = $curPage*$num;
        $res = array(
            "total" => $total,
            "num" => $num,
            "from" => (($curPage-1)*$num+1),
            "to" => $to>$total?$total:$to,
            "curPage" => $curPage,
            "nextPage" => $nextPage,
            "prevPage" => $prevPage
        );
        return $res;
    }

    /**
     * 辅助方法，通过where来统计总的信息数量
     * @param array $where
     * @return mixed
     */
    public function fn_GetTotalItems($where=array()){
        return M("contact")->where($where)->count();
    }

    /**
     * 辅助方法，通过where, order, offset查询相邻两条数据
     * @param $where
     * @param $offset
     */
    public function fn_FindNearbyItems($where, $order, $offset){
        $total = M("contact")->where($where)->count();
        $prevOffset = $offset>0?$offset-1:$total-1;
        $nextOffset = $offset>=$total-1?0:$offset+1;
        $prevItem = $this->fn_GetInfoByOffset($prevOffset, $where, $order);
        $nextItem = $this->fn_GetInfoByOffset($nextOffset, $where, $order);
        return array(
            "prev" => array("id"=>$prevItem["id"],"offset"=>$prevOffset),
            "next" => array("id"=>$nextItem["id"],"offset"=>$nextOffset),
        );
    }

}